package com.lp.multi.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: lp
 * @create: 2021-06-26 21:05
 * @description: 八锁现象：理解synchronized代码块运行时，cpu时间片不会切换
 * 主线程sleep足够时间(1秒)，A线程先拿到phone对象的锁,A线程获取锁后sleep时间超过主线程（4秒）
 * 执行结果:
 * A:get lock
 * 主线程执行完成!
 * A:send msg
 * B:call msg
 * 原因:主线程sleep期间，B线程还未创建，A线程先运行拿到了锁。A线程sleep 4秒完成前(抱着phone对象锁不释放)，虽然B线程已经进入准备运行
 * 状态，但是在A不释放锁前，无法获取锁。
 *
 * synchronized内,锁没有释放前，cpu时间片不会切换，代码会运行完成.如果释放了锁，线程再一次获得锁，代码在失去锁的位置继续运行。
 *
 */
public class ALock {
    public static void main(String[] args) {
        Phone0 phone = new Phone0();

        new Thread(()->{
                phone.sendMsg();
        },"A").start();

        new Thread(()->{
            //未获取锁前睡眠B线程,保证A线程先拿到锁
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            phone.call();
        },"B").start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程执行完成!");
    }
}

class Phone0{
    public synchronized void sendMsg(){
            System.out.println(Thread.currentThread().getName()+":"+"get lock");
        try {
            //抱着锁睡觉，不会释放锁
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //虽然执行很多次，但是cpu时间片并没有切换?
        for (int i = 0; i < 10; i++) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName()+":"+"send msg");
    }

    public synchronized void call(){
            System.out.println(Thread.currentThread().getName()+":"+"call msg");
    }

}
